package com.wuyan.warriorsoffate.ui.view


import android.util.Log
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Slider
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.wuyan.warriorsoffate.ui.theme.WeTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlin.math.log
import kotlin.math.roundToInt
//一个竖直滑动条
@Composable
fun WeSlider(
    //滑动条偏移0~1.0f
    offset: Float,
    //滑动条变化回调接口
    onChange:(offset:Float)->Unit,
    maxValue: Float = 1f,
    //互动条背景大小
    bgWidth:Dp=5.dp,
    bgColor: Color=WeTheme.colors.text.copy(alpha = 0.8f),
    onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {},
    onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {},
    modifier: Modifier=Modifier, content:@Composable () -> Unit){
    var height = 0
    var heightContext = 0
    Box(modifier = modifier
        .background(Color(red = 0, green = 0, blue = 0, alpha = 0))
        .layout { measurable, constraints ->
            val placeable = measurable.measure(constraints = constraints)
            height = placeable.height
            layout(placeable.width, placeable.height) {
                placeable.placeRelative(0, 0)
            }
        }) {
        Box(modifier = Modifier
            .fillMaxHeight()
            .width(bgWidth)
            .align(Alignment.Center)
            .background(bgColor, shape = CircleShape))
        Box(modifier = Modifier
            .wrapContentSize()
            .layout { measurable, constraints ->
                val placeable = measurable.measure(constraints = constraints)
                heightContext = placeable.height
                layout(placeable.width, placeable.height) {
                    placeable.placeRelative(0, 0)
                }
            }
            .align(Alignment.TopCenter)
            .offset {
                var offsety = 0
                if (offset / maxValue > 1.0f) {
                    offsety = height - heightContext
                } else if (offset < 0) {
                    offsety = 0
                } else {
                    offsety = ((offset / maxValue) * (height - heightContext)).toInt()
                }
                IntOffset(0, offsety)
            }
            .draggable(
                state = rememberDraggableState {
                    val temp = it / (height - heightContext)
                    if (it > 0) {
                        if (offset / maxValue + temp > 1.0f) {
                            onChange(maxValue)
                        } else {
                            onChange(offset + maxValue * temp)
                        }
                    } else {
                        if (offset / maxValue + temp < 0) {
                            onChange(0f)
                        } else {
                            onChange(offset + maxValue * temp)
                        }
                    }
                },
                orientation = Orientation.Vertical,
                onDragStarted = onDragStarted,
                onDragStopped = onDragStopped
            )
            .background(Color(red = 0, green = 0, blue = 0, alpha = 0))){
            content()
        }
    }
}
@ExperimentalAnimationApi
@Composable
fun WeColumn(modifier: Modifier = Modifier,
             state: LazyListState = rememberLazyListState(),
             contentPadding: PaddingValues = PaddingValues(0.dp),
             reverseLayout: Boolean = false,
             verticalArrangement: Arrangement.Vertical =
                 if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
             horizontalAlignment: Alignment.Horizontal = Alignment.Start,
             flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
             content: LazyListScope.() -> Unit){
    val scope= rememberCoroutineScope()
    val isDraggable= remember {
        mutableStateOf(false)
    }
    val offset = remember {
        mutableStateOf(0f)
    }
    Box(modifier = Modifier.wrapContentSize()) {
        LazyColumn(
            modifier,
            state,
            contentPadding,
            reverseLayout,
            verticalArrangement,
            horizontalAlignment,
            flingBehavior,
            content
        )
        AnimatedVisibility(visible = state.isScrollInProgress||isDraggable.value,
            enter = slideInHorizontally(
                initialOffsetX = {it},
                animationSpec = tween(durationMillis=500)
            ) + fadeIn(initialAlpha=0f,animationSpec=tween(durationMillis=500)),
            exit = slideOutHorizontally(
                targetOffsetX = {it},
                animationSpec = tween(durationMillis=2000 ,delayMillis = 2000)
            ) + fadeOut(targetAlpha=0f,animationSpec=tween(durationMillis=2000, delayMillis = 2000)),
            modifier = Modifier
                .wrapContentWidth()
                .align(Alignment.CenterEnd)
                .padding(WeTheme.weDp.paddingSmall * 2)
        ) {
            WeSlider(if (isDraggable.value) offset.value else getOffset(state), onChange = {
                offset.value=it
                if (state.layoutInfo.totalItemsCount>state.layoutInfo.visibleItemsInfo.size){
                    scope.launch {
                        state.scrollToItem((it*(state.layoutInfo.totalItemsCount-state.layoutInfo.visibleItemsInfo.size+1)).toInt())
                    }
                }
            }, bgWidth = WeTheme.weDp.paddingSmall, onDragStarted = {isDraggable.value=true}, onDragStopped = {isDraggable.value=false}){
                Box(modifier = Modifier
                    .size(WeTheme.weDp.paddingSmall * 2)
                    .background(WeTheme.colors.text, shape = CircleShape))
            }
        }
    }
}
fun getOffset(state: LazyListState):Float{
    if (state.layoutInfo.totalItemsCount>state.layoutInfo.visibleItemsInfo.size){
        return state.firstVisibleItemIndex.toFloat()/(state.layoutInfo.totalItemsCount-state.layoutInfo.visibleItemsInfo.size)
    }else{
        return 1.0f
    }
}